// function fn(x: string): string;
// function fn(x: number): number;
// function fn(x: string | number): string | number {
//   return x;
// }
// fn(1);
// type
// function fn<T>(x: T): T {
//   return x;
// }

// fn<number>(10);
// 泛型可以设置默认值
// 调用类型的时候没有传递泛型类型，用的泛型默认值
//  调用类型的时候传递了泛型，传递的泛型类型的权重大于泛型默认值
// interface ISpuItem<T = string> {
//   spuDesc: T;
//   spuName: string;
// }

// let spuItem: ISpuItem<number> = {
//   spuDesc: 10,
//   spuName: "",
// };

// 泛型约束
// interface ILength {
//   length: number;
// }
// function fn(x: ILength) {
//   return x.length;
// }
// console.log(fn("123"));

// Pick（挑选）、Omit（排除）、Partial（可选）、Required（必填）

interface ISpuItem {
  spuName: string;
  spuDesc: string;
  spuNum?: number;
  spuImg?: string;
}
type ISpuItem2 = Pick<ISpuItem, "spuDesc" | "spuImg">;
// ISpuItem2{
//     spuDesc: string;
//     spuImg: string;
// }

type ISpuItem3 = Omit<ISpuItem, "spuDesc" | "spuImg">;
// ISpuItem3{
//     spuName: string;
//     spuNum: number;
// }
// 根据源类型生成新类型，新类型所有项都是可选的
// type ISpuItem4 = Partial<ISpuItem>;
// let spuItem: ISpuItem4 = {};
// 根据源类型生成新类型，新类型所有项都是必选的
type ISpuItem5 = Required<ISpuItem>;
let spuItem: ISpuItem5 = {};
